home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2007 December / PCWKCD1207B.iso / Blogowanie poza sfera / Flock 0.9.1.3 stable / flock-0.9.1.3.en-US.win32.exe / flock / components / flockSearchvideoService.js < prev    next >
Text File  |  2007-10-12  |  19KB  |  557 lines

  1. //
  2. // BEGIN FLOCK GPL
  3. // 
  4. // Copyright Flock Inc. 2005-2007
  5. // http://flock.com
  6. // 
  7. // This file may be used under the terms of of the
  8. // GNU General Public License Version 2 or later (the "GPL"),
  9. // http://www.gnu.org/licenses/gpl.html
  10. // 
  11. // Software distributed under the License is distributed on an "AS IS" basis,
  12. // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. // for the specific language governing rights and limitations under the
  14. // License.
  15. // 
  16. // END FLOCK GPL
  17. //
  18.  
  19. const Cc = Components.classes;
  20. const Ci = Components.interfaces;
  21. const Cr = Components.results;
  22.  
  23. const ENABLE_DEBUG = true;
  24. function DEBUG(x) { if (ENABLE_DEBUG) debug("flockSearchvideoService: "+x+"\n"); }
  25.  
  26. const SEARCHVIDEO_TITLE                  = "Truveo Web Service";
  27. const SEARCHVIDEO_FAVICON                = "http://www.searchvideo.com/favicon.ico";
  28. const SEARCHVIDEO_CID                    = Components.ID("{31def21e-02d6-4d9a-848c-2c1895e50626}");
  29. const SEARCHVIDEO_CONTRACTID             = "@flock.com/?photo-api-searchvideo;1";
  30. const APPID                              = "1x1jhj64466mi12ia";
  31.  
  32. var gCompTK;
  33. var alreadySearched = false;
  34. function getCompTK() {
  35.   if (!gCompTK) {
  36.     gCompTK = Cc["@flock.com/singleton;1"].getService(Ci.flockISingleton)
  37.                 .getSingleton("chrome://browser/content/flock/services/common/load-compTK.js").wrappedJSObject;
  38.   }
  39.   return gCompTK;
  40. }
  41.  
  42.  
  43. function loadLibraryFromSpec(aSpec)
  44. {
  45.   var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
  46.                .getService(Ci.mozIJSSubScriptLoader);
  47.   loader.loadSubScript(aSpec);
  48. }
  49. loadLibraryFromSpec("chrome://browser/content/flock/photo/photoAPI.js");
  50.  
  51. function searchvideoPhoto() {}
  52.  
  53. searchvideoPhoto.prototype = {
  54.   id: "",
  55.   thumbnail: "",
  56.   webPageUrl: "",
  57.   midSizePhoto: "",
  58.   largeSizePhoto: "",
  59.   title: "",
  60.   username: "",
  61.   userid: "",
  62.   embedTag: "",
  63.   is_public: "true",
  64.   is_video: "true",
  65.   svcShortName: 'searchvideo',
  66.   has_miniView: "true",
  67.   buildTooltip: function( ) {
  68.     // do we have to use document from the window to ceate elements? -- ja
  69.     var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
  70.     var win = wm.getMostRecentWindow('navigator:browser');
  71.     if (!win) return null;
  72.  
  73.     var hbox = win.document.createElement('hbox');
  74.     var img = win.document.createElement('image');
  75.     img.setAttribute('src', this.icon );
  76.     hbox.appendChild(img);
  77.     var box = win.document.createElement('vbox');
  78.     box.setAttribute('style', 'max-width: 300px');
  79.     var title = win.document.createElement('label');
  80.     title.setAttribute('value', this.title );
  81.     title.setAttribute('crop', 'end');
  82.     box.appendChild(title);
  83.     var lbl = win.document.createElement('label');
  84.     lbl.setAttribute('value', this.username );
  85.     lbl.setAttribute('class', 'user');
  86.     box.appendChild(lbl);
  87.     hbox.appendChild(box)
  88.  
  89.     var vbox = win.document.createElement('vbox');
  90.     var cbox = win.document.createElement('cbox');
  91.     var largeImg = win.document.createElement('image');
  92.     largeImg.setAttribute('src', this.midSizePhoto);
  93.     largeImg.setAttribute('style', 'margin-bottom: 2px;');
  94.     var spacer = win.document.createElement('spacer');
  95.     spacer.setAttribute('flex', '1');
  96.     cbox.appendChild(largeImg);
  97.     cbox.appendChild(spacer);
  98.     vbox.appendChild(cbox);
  99.     vbox.appendChild(hbox);
  100.  
  101.     return vbox;
  102.   },
  103.   buildHTML: function ( ) {
  104.     return this.embedTag;
  105.   },
  106.   buildBBCode: function ( ) {
  107.     return '[url=' + this.webPageUrl + '][img]'+ this.midSizePhoto +'[/img][/url]';
  108.   },
  109.   buildMiniPage: function ( ) {
  110.     return this.webPageUrl;
  111.   },
  112.   QueryInterface: function(iid) {
  113.     if (!iid.equals(Ci.nsISupports) &&
  114.         !iid.equals(Ci.flockIPhoto)) {
  115.       throw Cr.NS_ERROR_NO_INTERFACE;
  116.     }
  117.     return this;
  118.   }
  119. };
  120.  
  121.  
  122. searchvideoPhoto.prototype.__defineGetter__('metaData', function () {
  123.   var metaData = Components.classes["@mozilla.org/hash-property-bag;1"].createInstance(Components.interfaces.nsIWritablePropertyBag2);
  124.   metaData.setPropertyAsAString("title", this.title);  
  125.   metaData.QueryInterface(Components.interfaces.nsIPropertyBag);
  126.   
  127.   // expose other metadata props here, then you can display them with custom xbls
  128.   // which extend from the generic photo binding
  129.   
  130.   return metaData;
  131. })
  132. // ====================================================
  133. // ========== BEGIN searchvideoService class ==========
  134. // ====================================================
  135.  
  136. function searchvideoService() {
  137.   this.url = "http://www.searchvideo.com";
  138.   this._ctk = {
  139.     interfaces: [
  140.       "nsISupports",
  141.       "nsIClassInfo",
  142.       "nsISupportsCString",
  143.       "nsIObserver",
  144.       "flockIPhotoAPI",
  145.       "flockIWebService",
  146.       "flockIMediaWebService",
  147.     ],
  148.     shortName: "searchvideo",
  149.     fullName: "Truveo",
  150.     description: SEARCHVIDEO_TITLE,
  151.     favicon: SEARCHVIDEO_FAVICON,
  152.     CID: SEARCHVIDEO_CID,
  153.     contractID: SEARCHVIDEO_CONTRACTID
  154.   };
  155.  
  156.   this.webDetective = Cc["@flock.com/account-utils;1"].getService(Ci.flockIAccountUtils).useWebDetective("searchvideo.xml");
  157.   this.faves_coop = Components.classes['@flock.com/singleton;1'].getService(Components.interfaces.flockISingleton).getSingleton('chrome://browser/content/flock/common/load-faves-coop.js').wrappedJSObject;
  158.   this._logger = Cc['@flock.com/logger;1'].createInstance(Ci.flockILogger);
  159.   this._logger.init('searchvideo');
  160. }
  161.  
  162. searchvideoService.prototype.serviceName = "Truveo";
  163. searchvideoService.prototype.shortName = "searchvideo";
  164. searchvideoService.prototype.iconUrl = "chrome://browser/skin/flock/photo/searchvideoIcon.png";
  165. searchvideoService.prototype.count = 1;
  166.  
  167.  
  168. searchvideoService.prototype.getPhotoFromRDFNode = 
  169. function (aRDFId)
  170. {
  171.   var newPhoto = new searchvideoPhoto();
  172.   var coopPhoto = this.faves_coop.get(aRDFId);
  173.   newPhoto.webPageUrl = coopPhoto.URL;
  174.   newPhoto.thumbnail = coopPhoto.thumbnail;
  175.   newPhoto.midSizePhoto = coopPhoto.midSizePhoto;
  176.   newPhoto.largeSizePhoto = coopPhoto.largeSizePhoto;
  177.   newPhoto.username = coopPhoto.username;
  178.   newPhoto.userid = coopPhoto.userid;
  179.   newPhoto.title = coopPhoto.name;
  180.   newPhoto.id = coopPhoto.photoid;
  181.   newPhoto.icon = coopPhoto.favicon;
  182.   newPhoto.uploadDate = coopPhoto.datevalue;
  183.   newPhoto.is_public = coopPhoto.is_public;
  184.   newPhoto.is_video = coopPhoto.is_video;
  185.   return newPhoto;
  186. }
  187.  
  188. searchvideoService.prototype.handlePhotosResult =
  189. function (aXML, aUserid) {
  190.   var rval = new Array();
  191.   var response = aXML.getElementsByTagName("VideoSet")[0];
  192.   var videoList = aXML.getElementsByTagName("Video");
  193.   for (var i = 0; i < videoList.length; i++) {
  194.     var video = videoList[i];
  195.  
  196.     var newPhoto = new searchvideoPhoto();
  197.     newPhoto.id = video.getElementsByTagName("id")[0].textContent;
  198.     newPhoto.title = video.getElementsByTagName("title")[0].textContent;
  199.     newPhoto.webPageUrl = video.getElementsByTagName("videoUrl")[0].textContent;
  200.     newPhoto.thumbnail = video.getElementsByTagName("thumbnailUrl")[0].textContent;
  201.     var largeThumbnail = video.getElementsByTagName("thumbnailUrlLarge");
  202.     if (largeThumbnail.length > 0) {
  203.       newPhoto.midSizePhoto = largeThumbnail[0].textContent;
  204.       newPhoto.largeSizePhoto = largeThumbnail[0].textContent;
  205.     }
  206.     else {
  207.       newPhoto.midSizePhoto = newPhoto.thumbnail;
  208.       newPhoto.largeSizePhoto = newPhoto.thumbnail;
  209.     }
  210.     newPhoto.username = video.getElementsByTagName("channel")[0].textContent;
  211.     newPhoto.userid = video.getElementsByTagName("channelUrl")[0].textContent;
  212.     var dateProduced = video.getElementsByTagName("dateProduced");
  213.     if (dateProduced.length > 0)
  214.       newPhoto.uploadDate = dateProduced[0].textContent;
  215.     else
  216.       newPhoto.uploadDate = video.getElementsByTagName("dateFound")[0].textContent;
  217.     newPhoto.is_public = true;
  218.     newPhoto.is_video = true;
  219.     newPhoto.embedTag = video.getElementsByTagName("videoResultEmbedTag")[0].textContent;
  220.     rval.push(newPhoto);
  221.   }
  222.   return rval;
  223. }
  224.  
  225. searchvideoService.prototype.queryChannel =
  226. function searchvideoService_queryChannel(aListener, aQueryString, aCount, aPage) {
  227.   var aQuery = new queryHelper(aQueryString);
  228.   var inst=this;
  229.   var myListener = {
  230.     onResult: function (aXML) {
  231.       var rval = inst.handlePhotosResult(aXML);
  232.       var enum_ = {
  233.         hasMoreElements: function() {
  234.           return (rval.length>0);
  235.         },
  236.         getNext: function() {
  237.           return rval.shift();
  238.         }
  239.       }
  240.       aListener.onSearchResult(enum_);
  241.     },
  242.     onError: function (aError) {
  243.       aListener.onError(aError);
  244.     }
  245.   }
  246.  
  247.   var params = {
  248.     results: (aCount ? aCount : 50),
  249.     start: (aPage ? aPage : 1)
  250.   };
  251.  
  252.   switch (aQuery.special) {
  253.     case "recent": params.query = "sort:mostRecent "; break;
  254.     case "topfav": params.query = "sort:topFavorites "; break;
  255.     case "pop": params.query = "sort:mostPopular "; break;
  256.     case "poptoday": params.query = "sort:mostPopularToday "; break;
  257.     case "popweek": params.query = "sort:mostPopularThisWeek "; break;
  258.     case "popmonth": params.query = "sort:mostPopularThisMonth "; break;
  259.     case "abc": params.query = "sort:mostPopular channel:ABC "; break;
  260.     case "myspace": params.query = "sort:mostPopular channel:MYSPACE "; break;
  261.     case "disney": params.query = "sort:mostPopular channel:Disney "; break;
  262.     default: params.query = "sort:vrank ";
  263.   }
  264.  
  265.   if (aQuery.search)
  266.        params.query += aQuery.search;
  267.  
  268.   this.call(myListener, "truveo.videos.getVideos", params);
  269. }
  270.  
  271. searchvideoService.prototype.search =
  272. function searchvideoService_search(aListener, aQueryString, aCount, aPage) {
  273.   
  274.   //this.count = this.count+aCount;
  275.   // Searchvideo only supports channel queries for now
  276.   if(aPage == 1) this.count = 1;
  277.   this.queryChannel(aListener, aQueryString, aCount, (aPage ? this.count : 1));
  278.   this.count = aCount + this.count;
  279. }
  280.  
  281. searchvideoService.prototype.supportsSearch =
  282. function searchvideoService_supportsSearch( aQueryString ) {
  283.   var aQuery = new queryHelper(aQueryString);
  284.   
  285.   if (aQuery.special) {
  286.     var channel = channels["special:" + aQuery.special];
  287.     if (channel) {
  288.       return channel.supportsSearch;
  289.     }
  290.   }
  291.  
  292.   if (aQuery.search) return false;
  293.   if (aQuery.user) return true;
  294.   return false;
  295. }
  296.  
  297. var channels = {
  298.   "special:all": {
  299.     title: "All",
  300.     supportsSearch: true
  301.   },
  302.   "special:topfav": {
  303.     title: "Top Favorites",
  304.     supportsSearch: true
  305.   },
  306.   "special:pop": {
  307.     title: "Most Popular",
  308.     supportsSearch: true
  309.   },
  310.   "special:abc": {
  311.     title: "Best of ABC",
  312.     supportsSearch: true
  313.   },
  314.   "special:myspace": {
  315.     title: "Best of MySpace",
  316.     supportsSearch: true
  317.   }
  318. /*  "special:disney": {
  319.     title: "Best of Disney",
  320.     supportsSearch: true
  321.   }
  322.   "poptoday": {
  323.     title: "Most Popular Today",
  324.     supportsSearch: true,
  325.   },
  326.   "popweek": {
  327.     title: "Most Popular This Week",
  328.     supportsSearch: true,
  329.   },
  330.   "popmonth": {
  331.     title: "Most Popular This Month",
  332.     supportsSearch: true,
  333.   },*/
  334. }
  335.  
  336. searchvideoService.prototype.getChannel =
  337. function searchvideoService_getChannel(aChannelId) {
  338.   if (!(aChannelId in channels)) return null;
  339.  
  340.   var nc = Cc["@flock.com/media-channel;1"].createInstance(Ci.flockIMediaChannel);
  341.   nc.id = aChannelId;
  342.   nc.title = channels[aChannelId].title
  343.   nc.supportsSearch = channels[aChannelId].supportsSearch;
  344.   return nc;
  345. }
  346.  
  347. searchvideoService.prototype.__defineGetter__("channels", function () {
  348.   var ar = new Array();
  349.  
  350.   for (var id in channels) {
  351.     var nc = Cc["@flock.com/media-channel;1"].createInstance(Ci.flockIMediaChannel);
  352.     nc.id = id;
  353.     nc.title = channels[id].title
  354.     nc.supportsSearch = channels[id].supportsSearch;
  355.     ar.push(nc);
  356.   }
  357.  
  358.   var rval = {
  359.     getNext: function() {
  360.       return ar.shift();
  361.     },
  362.     hasMoreElements: function() {
  363.       return (ar.length>0);
  364.     }
  365.   }
  366.   return rval;
  367. })
  368.  
  369. searchvideoService.prototype.getError =
  370. function searchvideoService_getError (aErrorType, aXML, aHTTPErrorCode) {
  371.   var error = Components.classes["@flock.com/error;1"].createInstance(Ci.flockIError);
  372.   if  (aErrorType == "HTTP_ERROR") {
  373.     error.errorCode = aHTTPErrorCode;
  374.   } else if (aErrorType == "SERVICE_ERROR") {
  375.     var errorCode;
  376.     var errorMessage;
  377.     var serviceErrorMessage;
  378.     try {
  379.       errorCode = aXML.getElementsByTagName("Error")[0].getAttribute('Code');
  380.       serviceErrorMessage = aXML.getElementsByTagName("error")[0].textContent;
  381.     } catch (ex) {
  382.       errorCode = "999" // in case the error xml is invalid
  383.     }
  384.  
  385.     switch (errorCode) {
  386.       case "1":  // API key missing (should never happen, but...)
  387.       case "14": // API key invalid
  388.       case "15": // API key over the daily query limit (I hope it will never happen)
  389.         error.errorCode = error.PHOTOSERVICE_INVALID_API_KEY;
  390.       break;
  391.  
  392.       case "2": // A method was not submitted with the request
  393.       case "3": // The query parameter was not submitted with the request
  394.       case "4": // The results parameter must be an integer between 1 and 50
  395.       case "5": // The query parameter was not submitted with the request
  396.       case "7": // The showAdult parameter must be 0 or 1
  397.       case "8": // The tagresults parameter must be an integer between 1 and 50
  398.       case "9": // The channelresults parameter must be an integer between 1 and 50
  399.       case "10": // The categoryresults parameter must be an integer between 1 and 50
  400.       case "11": // The userresults parameter must be an integer between 1 and 50
  401.       case "13": // The method you submitted with the request was not valid
  402.       case "21": // The showRelatedItems parameter must be 0 or 1
  403.         error.errorCode = error.PHOTOSERVICE_INVALID_QUERY;
  404.       break;
  405.  
  406.       case "12":
  407.         error.errorCode = error.PHOTOSERVICE_UNAVAILABLE;
  408.       break;
  409.  
  410.       case "999":
  411.         error.errorCode = error.PHOTOSERVICE_UNKNOWN_ERROR;
  412.       break;
  413.  
  414.       default:
  415.         error.errorCode = error.PHOTOSERVICE_UNKNOWN_ERROR;
  416.       break;
  417.     }
  418.   }
  419.   error.serviceErrorCode = errorCode;
  420.   error.serviceErrorString = serviceErrorMessage;
  421.   this._logger.error(error.errorString);
  422.   return error;
  423. };
  424.  
  425.  
  426. searchvideoService.prototype.call =
  427. function searchvideoService_call(aListener, aMethod, aParams) {
  428.   var inst = this;
  429.   this._req = Cc['@mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Ci.nsIXMLHttpRequest);
  430.   this._req.onreadystatechange = function (aEvt) {
  431.     if(inst._req.readyState == 4) {
  432.       if (inst._req.status/100 == 2) {
  433.         var dom = inst._req.responseXML;
  434.         var domResponse = dom.getElementsByTagName("Response")[0];
  435.         if (domResponse.firstChild.nodeName == "Error") {
  436.           var error = inst.getError('SERVICE_ERROR', dom, null);
  437.           aListener.onError(error);
  438.         }
  439.         else
  440.           aListener.onResult(domResponse);
  441.       }
  442.       else if (inst._req.status/100 == 4) {
  443.         var dom = inst._req.responseXML;
  444.         var domResponse = dom.getElementsByTagName("Response")[0];
  445.         if (domResponse && (domResponse.firstChild.nodeName == "Error")) {
  446.           var error = inst.getError('SERVICE_ERROR', dom, null);
  447.           aListener.onError(error);
  448.         }
  449.         else {
  450.           // http errors
  451.           aListener.onError(inst.getError("HTTP_ERROR", null, inst._req.status));
  452.         }
  453.       }
  454.       else {
  455.         // http errors
  456.         aListener.onError(inst.getError("HTTP_ERROR", null, inst._req.status));
  457.       }
  458.     }
  459.   };
  460.   var body = "appid="+APPID+"&method="+aMethod;
  461.   for (var k in aParams) {
  462.     var v = aParams[k];
  463.     if (v == null || v == undefined)
  464.       v = "";
  465.     body += ("&"+k+"="+escape(v));
  466.   }
  467.   dump("JMC: searchvideo querystring is " + body + "\n");
  468.   this._req.open("GET", 'http://api.searchvideo.com/apiv3?'+body, true);
  469.   this._req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded", false);
  470.   rval = this._req.send(null); 
  471. }
  472.  
  473. // BEGIN flockIMediaWebService interface
  474. searchvideoService.prototype.decorateForMedia =
  475. function searchvideoService_decorateForMedia(aDocument) {
  476.   DEBUG("{flockIMediaWebService}.decorateForMedia(aDocument)");
  477.   var results = Cc["@mozilla.org/hash-property-bag;1"]
  478.                           .createInstance(Ci.nsIWritablePropertyBag2);
  479.   if (this.webDetective.detect("searchvideo", "person", aDocument, results)) {
  480.     var mediaArr = new Array();
  481.     var media = {
  482.       name: results.getPropertyAsAString("username"),
  483.       query: "user:" + results.getPropertyAsAString("userid"),
  484.       label: results.getPropertyAsAString("username"),
  485.       favicon: this.icon,
  486.       service: this.shortName
  487.     }
  488.     mediaArr.push(media);
  489.     if (!aDocument._flock_decorations) {
  490.       aDocument._flock_decorations = new Object();
  491.     }
  492.     aDocument._flock_decorations.mediaArr = mediaArr;
  493.     this.obs.notifyObservers(aDocument, "media", "media:update");
  494.   }
  495. }
  496. // END flockIMediaWebService
  497.  
  498. // ========== END searchvideoService class ==========
  499.  
  500.  
  501. // ================================================
  502. // ========== BEGIN XPCOM Module support ==========
  503. // ================================================
  504.  
  505. function createModule(aParams) {
  506.   var Cc = Components.classes;
  507.   var Ci = Components.interfaces;
  508.   var Cr = Components.results;
  509.   return {
  510.     registerSelf: function (aCompMgr, aFileSpec, aLocation, aType) {
  511.       aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
  512.       aCompMgr.registerFactoryLocation( aParams.CID, aParams.componentName,
  513.                                         aParams.contractID, aFileSpec,
  514.                                         aLocation, aType );
  515.       var catMgr = Cc["@mozilla.org/categorymanager;1"]
  516.                      .getService(Ci.nsICategoryManager);
  517.       catMgr.addCategoryEntry( "flock-startup", aParams.componentName,
  518.                                "service,"+aParams.contractID, true, true ); 
  519.       if (!aParams.categories) { aParams.categories = []; }
  520.       for (var i = 0; i < aParams.categories.length; i++) {
  521.         var cat = aParams.categories[i];
  522.         catMgr.addCategoryEntry( cat.category, cat.entry,
  523.                                  cat.value, true, true ); 
  524.       }
  525.     },
  526.     getClassObject: function (aCompMgr, aCID, aIID) {
  527.       if (!aCID.equals(aParams.CID)) { throw Cr.NS_ERROR_NO_INTERFACE; }
  528.       if (!aIID.equals(Ci.nsIFactory)) { throw Cr.NS_ERROR_NOT_IMPLEMENTED; }
  529.       return { // Factory
  530.         createInstance: function (aOuter, aIID) {
  531.           if (aOuter != null) { throw Cr.NS_ERROR_NO_AGGREGATION; }
  532.           var comp = new aParams.componentClass();
  533.           if (aParams.implementationFunc) { aParams.implementationFunc(comp); }
  534.           return comp.QueryInterface(aIID);
  535.         }
  536.       };
  537.     },
  538.     canUnload: function (aCompMgr) { return true; }
  539.   };
  540. }
  541.  
  542. // NS Module entrypoint
  543. function NSGetModule(aCompMgr, aFileSpec) {
  544.   return createModule({
  545.     componentClass: searchvideoService,
  546.     CID: SEARCHVIDEO_CID,
  547.     contractID: SEARCHVIDEO_CONTRACTID,
  548.     componentName: "Searchvideo JS Component",
  549.     implementationFunc: function (aComp) { getCompTK().addAllInterfaces(aComp); },
  550.     categories: [ // "flock-startup" is automagically added
  551.       { category: "flockIPhotoAPI", entry: "searchvideo", value: SEARCHVIDEO_CONTRACTID }
  552.     ]
  553.   });
  554. }
  555.  
  556. // ========== END XPCOM Module support ==========
  557.